1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package sun.font;
27
28 import java.awt.Font;
29 import java.awt.FontFormatException;
30 import java.io.BufferedReader;
31 import java.io.File;
32 import java.io.FileInputStream;
33 import java.io.FilenameFilter;
34 import java.io.IOException;
35 import java.io.InputStreamReader;
36 import java.security.AccessController;
37 import java.security.PrivilegedAction;
38 import java.util.ArrayList;
39 import java.util.HashMap;
40 import java.util.HashSet;
41 import java.util.Hashtable;
42 import java.util.Iterator;
43 import java.util.Locale;
44 import java.util.Map;
45 import java.util.NoSuchElementException;
46 import java.util.StringTokenizer;
47 import java.util.TreeMap;
48 import java.util.Vector;
49 import java.util.concurrent.ConcurrentHashMap;
50
51 import javax.swing.plaf.FontUIResource;
52 import sun.awt.AppContext;
53 import sun.awt.FontConfiguration;
54 import sun.awt.SunToolkit;
55 import sun.java2d.FontSupport;
56 import sun.util.logging.PlatformLogger;
57
58
59
60
61
62
63
64 public abstract class SunFontManager implements FontSupport, FontManagerForSGE {
65
66 private static class TTFilter implements FilenameFilter {
67 public boolean accept(File dir,String name) {
68
69 int offset = name.length()-4;
70 if (offset <= 0) {
71 return false;
72 } else {
73 return(name.startsWith(".ttf", offset) ||
74 name.startsWith(".TTF", offset) ||
75 name.startsWith(".ttc", offset) ||
76 name.startsWith(".TTC", offset) ||
77 name.startsWith(".otf", offset) ||
78 name.startsWith(".OTF", offset));
79 }
80 }
81 }
82
83 private static class T1Filter implements FilenameFilter {
84 public boolean accept(File dir,String name) {
85 if (noType1Font) {
86 return false;
87 }
88
89 int offset = name.length()-4;
90 if (offset <= 0) {
91 return false;
92 } else {
93 return(name.startsWith(".pfa", offset) ||
94 name.startsWith(".pfb", offset) ||
95 name.startsWith(".PFA", offset) ||
96 name.startsWith(".PFB", offset));
97 }
98 }
99 }
100
101 private static class TTorT1Filter implements FilenameFilter {
102 public boolean accept(File dir, String name) {
103
104
105 int offset = name.length()-4;
106 if (offset <= 0) {
107 return false;
108 } else {
109 boolean isTT =
110 name.startsWith(".ttf", offset) ||
111 name.startsWith(".TTF", offset) ||
112 name.startsWith(".ttc", offset) ||
113 name.startsWith(".TTC", offset) ||
114 name.startsWith(".otf", offset) ||
115 name.startsWith(".OTF", offset);
116 if (isTT) {
117 return true;
118 } else if (noType1Font) {
119 return false;
120 } else {
121 return(name.startsWith(".pfa", offset) ||
122 name.startsWith(".pfb", offset) ||
123 name.startsWith(".PFA", offset) ||
124 name.startsWith(".PFB", offset));
125 }
126 }
127 }
128 }
129
130 public static final int FONTFORMAT_NONE = -1;
131 public static final int FONTFORMAT_TRUETYPE = 0;
132 public static final int FONTFORMAT_TYPE1 = 1;
133 public static final int FONTFORMAT_T2K = 2;
134 public static final int FONTFORMAT_TTC = 3;
135 public static final int FONTFORMAT_COMPOSITE = 4;
136 public static final int FONTFORMAT_NATIVE = 5;
137
138
139
140
141
142
143
144
145 private static final int CHANNELPOOLSIZE = 20;
146 private int lastPoolIndex = 0;
147 private FileFont fontFileCache[] = new FileFont[CHANNELPOOLSIZE];
148
149
150
151
152
153
154
155
156
157
158 private int maxCompFont = 0;
159 private CompositeFont [] compFonts = new CompositeFont[20];
160 private ConcurrentHashMap<String, CompositeFont>
161 compositeFonts = new ConcurrentHashMap<String, CompositeFont>();
162 private ConcurrentHashMap<String, PhysicalFont>
163 physicalFonts = new ConcurrentHashMap<String, PhysicalFont>();
164 private ConcurrentHashMap<String, PhysicalFont>
165 registeredFonts = new ConcurrentHashMap<String, PhysicalFont>();
166
167
168
169
170
171 private ConcurrentHashMap<String, Font2D>
172 fullNameToFont = new ConcurrentHashMap<String, Font2D>();
173
174
175
176
177 private HashMap<String, TrueTypeFont> localeFullNamesToFont;
178
179 private PhysicalFont defaultPhysicalFont;
180
181 static boolean longAddresses;
182 private boolean loaded1dot0Fonts = false;
183 boolean loadedAllFonts = false;
184 boolean loadedAllFontFiles = false;
185 HashMap<String,String> jreFontMap;
186 HashSet<String> jreLucidaFontFiles;
187 String[] jreOtherFontFiles;
188 boolean noOtherJREFontFiles = false;
189
190 public static final String lucidaFontName = "Lucida Sans Regular";
191 public static String jreLibDirName;
192 public static String jreFontDirName;
193 private static HashSet<String> missingFontFiles = null;
194 private String defaultFontName;
195 private String defaultFontFileName;
196 protected HashSet registeredFontFiles = new HashSet();
197
198 private ArrayList badFonts;
199
200
201
202
203
204
205
206 protected String fontPath;
207 private FontConfiguration fontConfig;
208
209
210
211
212
213 private boolean discoveredAllFonts = false;
214
215
216
217
218 private static final FilenameFilter ttFilter = new TTFilter();
219 private static final FilenameFilter t1Filter = new T1Filter();
220
221 private Font[] allFonts;
222 private String[] allFamilies;
223 private Locale lastDefaultLocale;
224
225 public static boolean noType1Font;
226
227
228 private static String[] STR_ARRAY = new String[0];
229
230
231
232
233
234 private boolean usePlatformFontMetrics = false;
235
236
237
238
239
240
241
242
243
244 public static SunFontManager getInstance() {
245 FontManager fm = FontManagerFactory.getInstance();
246 return (SunFontManager) fm;
247 }
248
249 public FilenameFilter getTrueTypeFilter() {
250 return ttFilter;
251 }
252
253 public FilenameFilter getType1Filter() {
254 return t1Filter;
255 }
256
257 @Override
258 public boolean usingPerAppContextComposites() {
259 return _usingPerAppContextComposites;
260 }
261
262 private void initJREFontMap() {
263
264
265
266
267
268
269
270
271
272
273
274
275 jreFontMap = new HashMap<String,String>();
276 jreLucidaFontFiles = new HashSet<String>();
277 if (isOpenJDK()) {
278 return;
279 }
280
281 jreFontMap.put("lucida sans0", "LucidaSansRegular.ttf");
282 jreFontMap.put("lucida sans1", "LucidaSansDemiBold.ttf");
283
284 jreFontMap.put("lucida sans regular0", "LucidaSansRegular.ttf");
285 jreFontMap.put("lucida sans regular1", "LucidaSansDemiBold.ttf");
286 jreFontMap.put("lucida sans bold1", "LucidaSansDemiBold.ttf");
287 jreFontMap.put("lucida sans demibold1", "LucidaSansDemiBold.ttf");
288
289
290 jreFontMap.put("lucida sans typewriter0",
291 "LucidaTypewriterRegular.ttf");
292 jreFontMap.put("lucida sans typewriter1", "LucidaTypewriterBold.ttf");
293
294 jreFontMap.put("lucida sans typewriter regular0",
295 "LucidaTypewriter.ttf");
296 jreFontMap.put("lucida sans typewriter regular1",
297 "LucidaTypewriterBold.ttf");
298 jreFontMap.put("lucida sans typewriter bold1",
299 "LucidaTypewriterBold.ttf");
300 jreFontMap.put("lucida sans typewriter demibold1",
301 "LucidaTypewriterBold.ttf");
302
303
304 jreFontMap.put("lucida bright0", "LucidaBrightRegular.ttf");
305 jreFontMap.put("lucida bright1", "LucidaBrightDemiBold.ttf");
306 jreFontMap.put("lucida bright2", "LucidaBrightItalic.ttf");
307 jreFontMap.put("lucida bright3", "LucidaBrightDemiItalic.ttf");
308
309 jreFontMap.put("lucida bright regular0", "LucidaBrightRegular.ttf");
310 jreFontMap.put("lucida bright regular1", "LucidaBrightDemiBold.ttf");
311 jreFontMap.put("lucida bright regular2", "LucidaBrightItalic.ttf");
312 jreFontMap.put("lucida bright regular3", "LucidaBrightDemiItalic.ttf");
313 jreFontMap.put("lucida bright bold1", "LucidaBrightDemiBold.ttf");
314 jreFontMap.put("lucida bright bold3", "LucidaBrightDemiItalic.ttf");
315 jreFontMap.put("lucida bright demibold1", "LucidaBrightDemiBold.ttf");
316 jreFontMap.put("lucida bright demibold3","LucidaBrightDemiItalic.ttf");
317 jreFontMap.put("lucida bright italic2", "LucidaBrightItalic.ttf");
318 jreFontMap.put("lucida bright italic3", "LucidaBrightDemiItalic.ttf");
319 jreFontMap.put("lucida bright bold italic3",
320 "LucidaBrightDemiItalic.ttf");
321 jreFontMap.put("lucida bright demibold italic3",
322 "LucidaBrightDemiItalic.ttf");
323 for (String ffile : jreFontMap.values()) {
324 jreLucidaFontFiles.add(ffile);
325 }
326 }
327
328 static {
329
330 java.security.AccessController.doPrivileged(
331 new java.security.PrivilegedAction() {
332
333 public Object run() {
334 FontManagerNativeLibrary.load();
335
336
337
338 initIDs();
339
340 switch (StrikeCache.nativeAddressSize) {
341 case 8: longAddresses = true; break;
342 case 4: longAddresses = false; break;
343 default: throw new RuntimeException("Unexpected address size");
344 }
345
346 noType1Font =
347 "true".equals(System.getProperty("sun.java2d.noType1Font"));
348 jreLibDirName =
349 System.getProperty("java.home","") + File.separator + "lib";
350 jreFontDirName = jreLibDirName + File.separator + "fonts";
351 File lucidaFile =
352 new File(jreFontDirName + File.separator + FontUtilities.LUCIDA_FILE_NAME);
353
354 return null;
355 }
356 });
357 }
358
359 public TrueTypeFont getEUDCFont() {
360
361 return null;
362 }
363
364
365 private static native void initIDs();
366
367 @SuppressWarnings("unchecked")
368 protected SunFontManager() {
369
370 initJREFontMap();
371 java.security.AccessController.doPrivileged(
372 new java.security.PrivilegedAction() {
373 public Object run() {
374 File badFontFile =
375 new File(jreFontDirName + File.separator +
376 "badfonts.txt");
377 if (badFontFile.exists()) {
378 FileInputStream fis = null;
379 try {
380 badFonts = new ArrayList();
381 fis = new FileInputStream(badFontFile);
382 InputStreamReader isr = new InputStreamReader(fis);
383 BufferedReader br = new BufferedReader(isr);
384 while (true) {
385 String name = br.readLine();
386 if (name == null) {
387 break;
388 } else {
389 if (FontUtilities.debugFonts()) {
390 FontUtilities.getLogger().warning("read bad font: " +
391 name);
392 }
393 badFonts.add(name);
394 }
395 }
396 } catch (IOException e) {
397 try {
398 if (fis != null) {
399 fis.close();
400 }
401 } catch (IOException ioe) {
402 }
403 }
404 }
405
406
407
408
409
410
411
412
413
414
415
416 if (FontUtilities.isLinux) {
417
418 registerFontDir(jreFontDirName);
419 }
420 registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK,
421 true, false);
422
423
424
425
426 fontConfig = createFontConfiguration();
427 if (isOpenJDK()) {
428 String[] fontInfo = getDefaultPlatformFont();
429 defaultFontName = fontInfo[0];
430 defaultFontFileName = fontInfo[1];
431 }
432
433 String extraFontPath = fontConfig.getExtraFontPath();
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461 boolean prependToPath = false;
462 boolean appendToPath = false;
463 String dbgFontPath =
464 System.getProperty("sun.java2d.fontpath");
465
466 if (dbgFontPath != null) {
467 if (dbgFontPath.startsWith("prepend:")) {
468 prependToPath = true;
469 dbgFontPath =
470 dbgFontPath.substring("prepend:".length());
471 } else if (dbgFontPath.startsWith("append:")) {
472 appendToPath = true;
473 dbgFontPath =
474 dbgFontPath.substring("append:".length());
475 }
476 }
477
478 if (FontUtilities.debugFonts()) {
479 PlatformLogger logger = FontUtilities.getLogger();
480 logger.info("JRE font directory: " + jreFontDirName);
481 logger.info("Extra font path: " + extraFontPath);
482 logger.info("Debug font path: " + dbgFontPath);
483 }
484
485 if (dbgFontPath != null) {
486
487
488
489 fontPath = getPlatformFontPath(noType1Font);
490
491 if (extraFontPath != null) {
492 fontPath =
493 extraFontPath + File.pathSeparator + fontPath;
494 }
495 if (appendToPath) {
496 fontPath =
497 fontPath + File.pathSeparator + dbgFontPath;
498 } else if (prependToPath) {
499 fontPath =
500 dbgFontPath + File.pathSeparator + fontPath;
501 } else {
502 fontPath = dbgFontPath;
503 }
504 registerFontDirs(fontPath);
505 } else if (extraFontPath != null) {
506
507
508
509
510
511
512
513
514
515
516
517
518
519 registerFontDirs(extraFontPath);
520 }
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 if (FontUtilities.isSolaris && Locale.JAPAN.equals(Locale.getDefault())) {
537 registerFontDir("/usr/openwin/lib/locale/ja/X11/fonts/TT");
538 }
539
540 initCompositeFonts(fontConfig, null);
541
542 return null;
543 }
544 });
545
546 boolean platformFont = AccessController.doPrivileged(
547 new PrivilegedAction<Boolean>() {
548 public Boolean run() {
549 String prop =
550 System.getProperty("java2d.font.usePlatformFont");
551 String env = System.getenv("JAVA2D_USEPLATFORMFONT");
552 return "true".equals(prop) || env != null;
553 }
554 });
555
556 if (platformFont) {
557 usePlatformFontMetrics = true;
558 System.out.println("Enabling platform font metrics for win32. This is an unsupported option.");
559 System.out.println("This yields incorrect composite font metrics as reported by 1.1.x releases.");
560 System.out.println("It is appropriate only for use by applications which do not use any Java 2");
561 System.out.println("functionality. This property will be removed in a later release.");
562 }
563 }
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595 public Font2DHandle getNewComposite(String family, int style,
596 Font2DHandle handle) {
597
598 if (!(handle.font2D instanceof CompositeFont)) {
599 return handle;
600 }
601
602 CompositeFont oldComp = (CompositeFont)handle.font2D;
603 PhysicalFont oldFont = oldComp.getSlotFont(0);
604
605 if (family == null) {
606 family = oldFont.getFamilyName(null);
607 }
608 if (style == -1) {
609 style = oldComp.getStyle();
610 }
611
612 Font2D newFont = findFont2D(family, style, NO_FALLBACK);
613 if (!(newFont instanceof PhysicalFont)) {
614 newFont = oldFont;
615 }
616 PhysicalFont physicalFont = (PhysicalFont)newFont;
617 CompositeFont dialog2D =
618 (CompositeFont)findFont2D("dialog", style, NO_FALLBACK);
619 if (dialog2D == null) {
620 return handle;
621 }
622 CompositeFont compFont = new CompositeFont(physicalFont, dialog2D);
623 Font2DHandle newHandle = new Font2DHandle(compFont);
624 return newHandle;
625 }
626
627 protected void registerCompositeFont(String compositeName,
628 String[] componentFileNames,
629 String[] componentNames,
630 int numMetricsSlots,
631 int[] exclusionRanges,
632 int[] exclusionMaxIndex,
633 boolean defer) {
634
635 CompositeFont cf = new CompositeFont(compositeName,
636 componentFileNames,
637 componentNames,
638 numMetricsSlots,
639 exclusionRanges,
640 exclusionMaxIndex, defer, this);
641 addCompositeToFontList(cf, Font2D.FONT_CONFIG_RANK);
642 synchronized (compFonts) {
643 compFonts[maxCompFont++] = cf;
644 }
645 }
646
647
648
649
650
651 protected static void registerCompositeFont(String compositeName,
652 String[] componentFileNames,
653 String[] componentNames,
654 int numMetricsSlots,
655 int[] exclusionRanges,
656 int[] exclusionMaxIndex,
657 boolean defer,
658 ConcurrentHashMap<String, Font2D>
659 altNameCache) {
660
661 CompositeFont cf = new CompositeFont(compositeName,
662 componentFileNames,
663 componentNames,
664 numMetricsSlots,
665 exclusionRanges,
666 exclusionMaxIndex, defer,
667 SunFontManager.getInstance());
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 Font2D oldFont = (Font2D)
683 altNameCache.get(compositeName.toLowerCase(Locale.ENGLISH));
684 if (oldFont instanceof CompositeFont) {
685 oldFont.handle.font2D = cf;
686 }
687 altNameCache.put(compositeName.toLowerCase(Locale.ENGLISH), cf);
688 }
689
690 private void addCompositeToFontList(CompositeFont f, int rank) {
691
692 if (FontUtilities.isLogging()) {
693 FontUtilities.getLogger().info("Add to Family "+ f.familyName +
694 ", Font " + f.fullName + " rank="+rank);
695 }
696 f.setRank(rank);
697 compositeFonts.put(f.fullName, f);
698 fullNameToFont.put(f.fullName.toLowerCase(Locale.ENGLISH), f);
699
700 FontFamily family = FontFamily.getFamily(f.familyName);
701 if (family == null) {
702 family = new FontFamily(f.familyName, true, rank);
703 }
704 family.setFont(f, f.style);
705 }
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738 private PhysicalFont addToFontList(PhysicalFont f, int rank) {
739
740 String fontName = f.fullName;
741 String familyName = f.familyName;
742 if (fontName == null || "".equals(fontName)) {
743 return null;
744 }
745 if (compositeFonts.containsKey(fontName)) {
746
747 return null;
748 }
749 f.setRank(rank);
750 if (!physicalFonts.containsKey(fontName)) {
751 if (FontUtilities.isLogging()) {
752 FontUtilities.getLogger().info("Add to Family "+familyName +
753 ", Font " + fontName + " rank="+rank);
754 }
755 physicalFonts.put(fontName, f);
756 FontFamily family = FontFamily.getFamily(familyName);
757 if (family == null) {
758 family = new FontFamily(familyName, false, rank);
759 family.setFont(f, f.style);
760 } else if (family.getRank() >= rank) {
761 family.setFont(f, f.style);
762 }
763 fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH), f);
764 return f;
765 } else {
766 PhysicalFont newFont = f;
767 PhysicalFont oldFont = physicalFonts.get(fontName);
768 if (oldFont == null) {
769 return null;
770 }
771
772
773
774 if (oldFont.getRank() >= rank) {
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794 if (oldFont.mapper != null && rank > Font2D.FONT_CONFIG_RANK) {
795 return oldFont;
796 }
797
798
799
800
801
802
803 if (oldFont.getRank() == rank) {
804 if (oldFont instanceof TrueTypeFont &&
805 newFont instanceof TrueTypeFont) {
806 TrueTypeFont oldTTFont = (TrueTypeFont)oldFont;
807 TrueTypeFont newTTFont = (TrueTypeFont)newFont;
808 if (oldTTFont.fileSize >= newTTFont.fileSize) {
809 return oldFont;
810 }
811 } else {
812 return oldFont;
813 }
814 }
815
816
817
818
819
820
821
822
823
824 if (oldFont.platName.startsWith(jreFontDirName)) {
825 if (FontUtilities.isLogging()) {
826 FontUtilities.getLogger()
827 .warning("Unexpected attempt to replace a JRE " +
828 " font " + fontName + " from " +
829 oldFont.platName +
830 " with " + newFont.platName);
831 }
832 return oldFont;
833 }
834
835 if (FontUtilities.isLogging()) {
836 FontUtilities.getLogger()
837 .info("Replace in Family " + familyName +
838 ",Font " + fontName + " new rank="+rank +
839 " from " + oldFont.platName +
840 " with " + newFont.platName);
841 }
842 replaceFont(oldFont, newFont);
843 physicalFonts.put(fontName, newFont);
844 fullNameToFont.put(fontName.toLowerCase(Locale.ENGLISH),
845 newFont);
846
847 FontFamily family = FontFamily.getFamily(familyName);
848 if (family == null) {
849 family = new FontFamily(familyName, false, rank);
850 family.setFont(newFont, newFont.style);
851 } else if (family.getRank() >= rank) {
852 family.setFont(newFont, newFont.style);
853 }
854 return newFont;
855 } else {
856 return oldFont;
857 }
858 }
859 }
860
861 public Font2D[] getRegisteredFonts() {
862 PhysicalFont[] physFonts = getPhysicalFonts();
863 int mcf = maxCompFont;
864 Font2D[] regFonts = new Font2D[physFonts.length+mcf];
865 System.arraycopy(compFonts, 0, regFonts, 0, mcf);
866 System.arraycopy(physFonts, 0, regFonts, mcf, physFonts.length);
867 return regFonts;
868 }
869
870 protected PhysicalFont[] getPhysicalFonts() {
871 return physicalFonts.values().toArray(new PhysicalFont[0]);
872 }
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888 private static final class FontRegistrationInfo {
889
890 String fontFilePath;
891 String[] nativeNames;
892 int fontFormat;
893 boolean javaRasterizer;
894 int fontRank;
895
896 FontRegistrationInfo(String fontPath, String[] names, int format,
897 boolean useJavaRasterizer, int rank) {
898 this.fontFilePath = fontPath;
899 this.nativeNames = names;
900 this.fontFormat = format;
901 this.javaRasterizer = useJavaRasterizer;
902 this.fontRank = rank;
903 }
904 }
905
906 private final ConcurrentHashMap<String, FontRegistrationInfo>
907 deferredFontFiles =
908 new ConcurrentHashMap<String, FontRegistrationInfo>();
909 private final ConcurrentHashMap<String, Font2DHandle>
910 initialisedFonts = new ConcurrentHashMap<String, Font2DHandle>();
911
912
913
914
915
916
917
918 protected synchronized void initialiseDeferredFonts() {
919 for (String fileName : deferredFontFiles.keySet()) {
920 initialiseDeferredFont(fileName);
921 }
922 }
923
924 protected synchronized void registerDeferredJREFonts(String jreDir) {
925 for (FontRegistrationInfo info : deferredFontFiles.values()) {
926 if (info.fontFilePath != null &&
927 info.fontFilePath.startsWith(jreDir)) {
928 initialiseDeferredFont(info.fontFilePath);
929 }
930 }
931 }
932
933 public boolean isDeferredFont(String fileName) {
934 return deferredFontFiles.containsKey(fileName);
935 }
936
937
938
939
940
941
942
943
944
945
946 public
947 PhysicalFont findJREDeferredFont(String name, int style) {
948
949 PhysicalFont physicalFont;
950 String nameAndStyle = name.toLowerCase(Locale.ENGLISH) + style;
951 String fileName = jreFontMap.get(nameAndStyle);
952 if (fileName != null) {
953 fileName = jreFontDirName + File.separator + fileName;
954 if (deferredFontFiles.get(fileName) != null) {
955 physicalFont = initialiseDeferredFont(fileName);
956 if (physicalFont != null &&
957 (physicalFont.getFontName(null).equalsIgnoreCase(name) ||
958 physicalFont.getFamilyName(null).equalsIgnoreCase(name))
959 && physicalFont.style == style) {
960 return physicalFont;
961 }
962 }
963 }
964
965
966
967
968
969
970
971
972
973
974 if (noOtherJREFontFiles) {
975 return null;
976 }
977 synchronized (jreLucidaFontFiles) {
978 if (jreOtherFontFiles == null) {
979 HashSet<String> otherFontFiles = new HashSet<String>();
980 for (String deferredFile : deferredFontFiles.keySet()) {
981 File file = new File(deferredFile);
982 String dir = file.getParent();
983 String fname = file.getName();
984
985
986
987 if (dir == null ||
988 !dir.equals(jreFontDirName) ||
989 jreLucidaFontFiles.contains(fname)) {
990 continue;
991 }
992 otherFontFiles.add(deferredFile);
993 }
994 jreOtherFontFiles = otherFontFiles.toArray(STR_ARRAY);
995 if (jreOtherFontFiles.length == 0) {
996 noOtherJREFontFiles = true;
997 }
998 }
999
1000 for (int i=0; i<jreOtherFontFiles.length;i++) {
1001 fileName = jreOtherFontFiles[i];
1002 if (fileName == null) {
1003 continue;
1004 }
1005 jreOtherFontFiles[i] = null;
1006 physicalFont = initialiseDeferredFont(fileName);
1007 if (physicalFont != null &&
1008 (physicalFont.getFontName(null).equalsIgnoreCase(name) ||
1009 physicalFont.getFamilyName(null).equalsIgnoreCase(name))
1010 && physicalFont.style == style) {
1011 return physicalFont;
1012 }
1013 }
1014 }
1015
1016 return null;
1017 }
1018
1019
1020 private PhysicalFont findOtherDeferredFont(String name, int style) {
1021 for (String fileName : deferredFontFiles.keySet()) {
1022 File file = new File(fileName);
1023 String dir = file.getParent();
1024 String fname = file.getName();
1025 if (dir != null &&
1026 dir.equals(jreFontDirName) &&
1027 jreLucidaFontFiles.contains(fname)) {
1028 continue;
1029 }
1030 PhysicalFont physicalFont = initialiseDeferredFont(fileName);
1031 if (physicalFont != null &&
1032 (physicalFont.getFontName(null).equalsIgnoreCase(name) ||
1033 physicalFont.getFamilyName(null).equalsIgnoreCase(name)) &&
1034 physicalFont.style == style) {
1035 return physicalFont;
1036 }
1037 }
1038 return null;
1039 }
1040
1041 private PhysicalFont findDeferredFont(String name, int style) {
1042
1043 PhysicalFont physicalFont = findJREDeferredFont(name, style);
1044 if (physicalFont != null) {
1045 return physicalFont;
1046 } else {
1047 return findOtherDeferredFont(name, style);
1048 }
1049 }
1050
1051 public void registerDeferredFont(String fileNameKey,
1052 String fullPathName,
1053 String[] nativeNames,
1054 int fontFormat,
1055 boolean useJavaRasterizer,
1056 int fontRank) {
1057 FontRegistrationInfo regInfo =
1058 new FontRegistrationInfo(fullPathName, nativeNames, fontFormat,
1059 useJavaRasterizer, fontRank);
1060 deferredFontFiles.put(fileNameKey, regInfo);
1061 }
1062
1063
1064 public synchronized
1065 PhysicalFont initialiseDeferredFont(String fileNameKey) {
1066
1067 if (fileNameKey == null) {
1068 return null;
1069 }
1070 if (FontUtilities.isLogging()) {
1071 FontUtilities.getLogger()
1072 .info("Opening deferred font file " + fileNameKey);
1073 }
1074
1075 PhysicalFont physicalFont;
1076 FontRegistrationInfo regInfo = deferredFontFiles.get(fileNameKey);
1077 if (regInfo != null) {
1078 deferredFontFiles.remove(fileNameKey);
1079 physicalFont = registerFontFile(regInfo.fontFilePath,
1080 regInfo.nativeNames,
1081 regInfo.fontFormat,
1082 regInfo.javaRasterizer,
1083 regInfo.fontRank);
1084
1085
1086 if (physicalFont != null) {
1087
1088
1089
1090 initialisedFonts.put(fileNameKey, physicalFont.handle);
1091 } else {
1092 initialisedFonts.put(fileNameKey,
1093 getDefaultPhysicalFont().handle);
1094 }
1095 } else {
1096 Font2DHandle handle = initialisedFonts.get(fileNameKey);
1097 if (handle == null) {
1098
1099 physicalFont = getDefaultPhysicalFont();
1100 } else {
1101 physicalFont = (PhysicalFont)(handle.font2D);
1102 }
1103 }
1104 return physicalFont;
1105 }
1106
1107 public boolean isRegisteredFontFile(String name) {
1108 return registeredFonts.containsKey(name);
1109 }
1110
1111 public PhysicalFont getRegisteredFontFile(String name) {
1112 return registeredFonts.get(name);
1113 }
1114
1115
1116
1117
1118
1119 public PhysicalFont registerFontFile(String fileName,
1120 String[] nativeNames,
1121 int fontFormat,
1122 boolean useJavaRasterizer,
1123 int fontRank) {
1124
1125 PhysicalFont regFont = registeredFonts.get(fileName);
1126 if (regFont != null) {
1127 return regFont;
1128 }
1129
1130 PhysicalFont physicalFont = null;
1131 try {
1132 String name;
1133
1134 switch (fontFormat) {
1135
1136 case FONTFORMAT_TRUETYPE:
1137 int fn = 0;
1138 TrueTypeFont ttf;
1139 do {
1140 ttf = new TrueTypeFont(fileName, nativeNames, fn++,
1141 useJavaRasterizer);
1142 PhysicalFont pf = addToFontList(ttf, fontRank);
1143 if (physicalFont == null) {
1144 physicalFont = pf;
1145 }
1146 }
1147 while (fn < ttf.getFontCount());
1148 break;
1149
1150 case FONTFORMAT_TYPE1:
1151 Type1Font t1f = new Type1Font(fileName, nativeNames);
1152 physicalFont = addToFontList(t1f, fontRank);
1153 break;
1154
1155 case FONTFORMAT_NATIVE:
1156 NativeFont nf = new NativeFont(fileName, false);
1157 physicalFont = addToFontList(nf, fontRank);
1158 default:
1159
1160 }
1161 if (FontUtilities.isLogging()) {
1162 FontUtilities.getLogger()
1163 .info("Registered file " + fileName + " as font " +
1164 physicalFont + " rank=" + fontRank);
1165 }
1166 } catch (FontFormatException ffe) {
1167 if (FontUtilities.isLogging()) {
1168 FontUtilities.getLogger().warning("Unusable font: " +
1169 fileName + " " + ffe.toString());
1170 }
1171 }
1172 if (physicalFont != null &&
1173 fontFormat != FONTFORMAT_NATIVE) {
1174 registeredFonts.put(fileName, physicalFont);
1175 }
1176 return physicalFont;
1177 }
1178
1179 public void registerFonts(String[] fileNames,
1180 String[][] nativeNames,
1181 int fontCount,
1182 int fontFormat,
1183 boolean useJavaRasterizer,
1184 int fontRank, boolean defer) {
1185
1186 for (int i=0; i < fontCount; i++) {
1187 if (defer) {
1188 registerDeferredFont(fileNames[i],fileNames[i], nativeNames[i],
1189 fontFormat, useJavaRasterizer, fontRank);
1190 } else {
1191 registerFontFile(fileNames[i], nativeNames[i],
1192 fontFormat, useJavaRasterizer, fontRank);
1193 }
1194 }
1195 }
1196
1197
1198
1199
1200
1201
1202
1203 public PhysicalFont getDefaultPhysicalFont() {
1204 if (defaultPhysicalFont == null) {
1205
1206
1207
1208
1209
1210
1211
1212 defaultPhysicalFont = (PhysicalFont)
1213 findFont2D("Lucida Sans Regular", Font.PLAIN, NO_FALLBACK);
1214 if (defaultPhysicalFont == null) {
1215 defaultPhysicalFont = (PhysicalFont)
1216 findFont2D("Arial", Font.PLAIN, NO_FALLBACK);
1217 }
1218 if (defaultPhysicalFont == null) {
1219
1220
1221
1222
1223
1224
1225 Iterator i = physicalFonts.values().iterator();
1226 if (i.hasNext()) {
1227 defaultPhysicalFont = (PhysicalFont)i.next();
1228 } else {
1229 throw new Error("Probable fatal error:No fonts found.");
1230 }
1231 }
1232 }
1233 return defaultPhysicalFont;
1234 }
1235
1236 public CompositeFont getDefaultLogicalFont(int style) {
1237 return (CompositeFont)findFont2D("dialog", style, NO_FALLBACK);
1238 }
1239
1240
1241
1242
1243
1244 private static String dotStyleStr(int num) {
1245 switch(num){
1246 case Font.BOLD:
1247 return ".bold";
1248 case Font.ITALIC:
1249 return ".italic";
1250 case Font.ITALIC | Font.BOLD:
1251 return ".bolditalic";
1252 default:
1253 return ".plain";
1254 }
1255 }
1256
1257
1258
1259
1260
1261 protected void
1262 populateFontFileNameMap(HashMap<String,String> fontToFileMap,
1263 HashMap<String,String> fontToFamilyNameMap,
1264 HashMap<String,ArrayList<String>>
1265 familyToFontListMap,
1266 Locale locale) {
1267 }
1268
1269
1270
1271
1272
1273
1274 private HashMap<String,String> fontToFileMap = null;
1275
1276
1277
1278
1279
1280 private HashMap<String,String> fontToFamilyNameMap = null;
1281
1282
1283
1284
1285
1286
1287 private HashMap<String,ArrayList<String>> familyToFontListMap= null;
1288
1289
1290 private String[] pathDirs = null;
1291
1292 private boolean haveCheckedUnreferencedFontFiles;
1293
1294 private String[] getFontFilesFromPath(boolean noType1) {
1295 final FilenameFilter filter;
1296 if (noType1) {
1297 filter = ttFilter;
1298 } else {
1299 filter = new TTorT1Filter();
1300 }
1301 return (String[])AccessController.doPrivileged(new PrivilegedAction() {
1302 public Object run() {
1303 if (pathDirs.length == 1) {
1304 File dir = new File(pathDirs[0]);
1305 String[] files = dir.list(filter);
1306 if (files == null) {
1307 return new String[0];
1308 }
1309 for (int f=0; f<files.length; f++) {
1310 files[f] = files[f].toLowerCase();
1311 }
1312 return files;
1313 } else {
1314 ArrayList<String> fileList = new ArrayList<String>();
1315 for (int i = 0; i< pathDirs.length; i++) {
1316 File dir = new File(pathDirs[i]);
1317 String[] files = dir.list(filter);
1318 if (files == null) {
1319 continue;
1320 }
1321 for (int f=0; f<files.length ; f++) {
1322 fileList.add(files[f].toLowerCase());
1323 }
1324 }
1325 return fileList.toArray(STR_ARRAY);
1326 }
1327 }
1328 });
1329 }
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351 private void resolveWindowsFonts() {
1352
1353 ArrayList<String> unmappedFontNames = null;
1354 for (String font : fontToFamilyNameMap.keySet()) {
1355 String file = fontToFileMap.get(font);
1356 if (file == null) {
1357 if (font.indexOf(" ") > 0) {
1358 String newName = font.replaceFirst(" ", " ");
1359 file = fontToFileMap.get(newName);
1360
1361
1362
1363 if (file != null &&
1364 !fontToFamilyNameMap.containsKey(newName)) {
1365 fontToFileMap.remove(newName);
1366 fontToFileMap.put(font, file);
1367 }
1368 } else if (font.equals("marlett")) {
1369 fontToFileMap.put(font, "marlett.ttf");
1370 } else if (font.equals("david")) {
1371 file = fontToFileMap.get("david regular");
1372 if (file != null) {
1373 fontToFileMap.remove("david regular");
1374 fontToFileMap.put("david", file);
1375 }
1376 } else {
1377 if (unmappedFontNames == null) {
1378 unmappedFontNames = new ArrayList<String>();
1379 }
1380 unmappedFontNames.add(font);
1381 }
1382 }
1383 }
1384
1385 if (unmappedFontNames != null) {
1386 HashSet<String> unmappedFontFiles = new HashSet<String>();
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417 HashMap<String,String> ffmapCopy =
1418 (HashMap<String,String>)(fontToFileMap.clone());
1419 for (String key : fontToFamilyNameMap.keySet()) {
1420 ffmapCopy.remove(key);
1421 }
1422 for (String key : ffmapCopy.keySet()) {
1423 unmappedFontFiles.add(ffmapCopy.get(key));
1424 fontToFileMap.remove(key);
1425 }
1426
1427 resolveFontFiles(unmappedFontFiles, unmappedFontNames);
1428
1429
1430
1431
1432
1433
1434 if (unmappedFontNames.size() > 0) {
1435
1436
1437
1438
1439
1440 ArrayList<String> registryFiles = new ArrayList<String>();
1441
1442 for (String regFile : fontToFileMap.values()) {
1443 registryFiles.add(regFile.toLowerCase());
1444 }
1445
1446
1447
1448
1449
1450 for (String pathFile : getFontFilesFromPath(true)) {
1451 if (!registryFiles.contains(pathFile)) {
1452 unmappedFontFiles.add(pathFile);
1453 }
1454 }
1455
1456 resolveFontFiles(unmappedFontFiles, unmappedFontNames);
1457 }
1458
1459
1460
1461
1462 if (unmappedFontNames.size() > 0) {
1463 int sz = unmappedFontNames.size();
1464 for (int i=0; i<sz; i++) {
1465 String name = unmappedFontNames.get(i);
1466 String familyName = fontToFamilyNameMap.get(name);
1467 if (familyName != null) {
1468 ArrayList family = familyToFontListMap.get(familyName);
1469 if (family != null) {
1470 if (family.size() <= 1) {
1471 familyToFontListMap.remove(familyName);
1472 }
1473 }
1474 }
1475 fontToFamilyNameMap.remove(name);
1476 if (FontUtilities.isLogging()) {
1477 FontUtilities.getLogger()
1478 .info("No file for font:" + name);
1479 }
1480 }
1481 }
1482 }
1483 }
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497 private synchronized void checkForUnreferencedFontFiles() {
1498 if (haveCheckedUnreferencedFontFiles) {
1499 return;
1500 }
1501 haveCheckedUnreferencedFontFiles = true;
1502 if (!FontUtilities.isWindows) {
1503 return;
1504 }
1505
1506
1507
1508
1509 ArrayList<String> registryFiles = new ArrayList<String>();
1510 for (String regFile : fontToFileMap.values()) {
1511 registryFiles.add(regFile.toLowerCase());
1512 }
1513
1514
1515
1516
1517
1518
1519
1520
1521 HashMap<String,String> fontToFileMap2 = null;
1522 HashMap<String,String> fontToFamilyNameMap2 = null;
1523 HashMap<String,ArrayList<String>> familyToFontListMap2 = null;;
1524
1525 for (String pathFile : getFontFilesFromPath(false)) {
1526 if (!registryFiles.contains(pathFile)) {
1527 if (FontUtilities.isLogging()) {
1528 FontUtilities.getLogger()
1529 .info("Found non-registry file : " + pathFile);
1530 }
1531 PhysicalFont f = registerFontFile(getPathName(pathFile));
1532 if (f == null) {
1533 continue;
1534 }
1535 if (fontToFileMap2 == null) {
1536 fontToFileMap2 = new HashMap<String,String>(fontToFileMap);
1537 fontToFamilyNameMap2 =
1538 new HashMap<String,String>(fontToFamilyNameMap);
1539 familyToFontListMap2 = new
1540 HashMap<String,ArrayList<String>>(familyToFontListMap);
1541 }
1542 String fontName = f.getFontName(null);
1543 String family = f.getFamilyName(null);
1544 String familyLC = family.toLowerCase();
1545 fontToFamilyNameMap2.put(fontName, family);
1546 fontToFileMap2.put(fontName, pathFile);
1547 ArrayList<String> fonts = familyToFontListMap2.get(familyLC);
1548 if (fonts == null) {
1549 fonts = new ArrayList<String>();
1550 } else {
1551 fonts = new ArrayList<String>(fonts);
1552 }
1553 fonts.add(fontName);
1554 familyToFontListMap2.put(familyLC, fonts);
1555 }
1556 }
1557 if (fontToFileMap2 != null) {
1558 fontToFileMap = fontToFileMap2;
1559 familyToFontListMap = familyToFontListMap2;
1560 fontToFamilyNameMap = fontToFamilyNameMap2;
1561 }
1562 }
1563
1564 private void resolveFontFiles(HashSet<String> unmappedFiles,
1565 ArrayList<String> unmappedFonts) {
1566
1567 Locale l = SunToolkit.getStartupLocale();
1568
1569 for (String file : unmappedFiles) {
1570 try {
1571 int fn = 0;
1572 TrueTypeFont ttf;
1573 String fullPath = getPathName(file);
1574 if (FontUtilities.isLogging()) {
1575 FontUtilities.getLogger()
1576 .info("Trying to resolve file " + fullPath);
1577 }
1578 do {
1579 ttf = new TrueTypeFont(fullPath, null, fn++, false);
1580
1581 String fontName = ttf.getFontName(l).toLowerCase();
1582 if (unmappedFonts.contains(fontName)) {
1583 fontToFileMap.put(fontName, file);
1584 unmappedFonts.remove(fontName);
1585 if (FontUtilities.isLogging()) {
1586 FontUtilities.getLogger()
1587 .info("Resolved absent registry entry for " +
1588 fontName + " located in " + fullPath);
1589 }
1590 }
1591 }
1592 while (fn < ttf.getFontCount());
1593 } catch (Exception e) {
1594 }
1595 }
1596 }
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611 public static class FamilyDescription {
1612 public String familyName;
1613 public String plainFullName;
1614 public String boldFullName;
1615 public String italicFullName;
1616 public String boldItalicFullName;
1617 public String plainFileName;
1618 public String boldFileName;
1619 public String italicFileName;
1620 public String boldItalicFileName;
1621 }
1622
1623 static HashMap<String, FamilyDescription> platformFontMap;
1624
1625
1626
1627
1628 public HashMap<String, FamilyDescription> populateHardcodedFileNameMap() {
1629 return new HashMap<String, FamilyDescription>(0);
1630 }
1631
1632 Font2D findFontFromPlatformMap(String lcName, int style) {
1633 if (platformFontMap == null) {
1634 platformFontMap = populateHardcodedFileNameMap();
1635 }
1636
1637 if (platformFontMap == null || platformFontMap.size() == 0) {
1638 return null;
1639 }
1640
1641 int spaceIndex = lcName.indexOf(' ');
1642 String firstWord = lcName;
1643 if (spaceIndex > 0) {
1644 firstWord = lcName.substring(0, spaceIndex);
1645 }
1646
1647 FamilyDescription fd = platformFontMap.get(firstWord);
1648 if (fd == null) {
1649 return null;
1650 }
1651
1652
1653
1654
1655
1656
1657 int styleIndex = -1;
1658 if (lcName.equalsIgnoreCase(fd.plainFullName)) {
1659 styleIndex = 0;
1660 } else if (lcName.equalsIgnoreCase(fd.boldFullName)) {
1661 styleIndex = 1;
1662 } else if (lcName.equalsIgnoreCase(fd.italicFullName)) {
1663 styleIndex = 2;
1664 } else if (lcName.equalsIgnoreCase(fd.boldItalicFullName)) {
1665 styleIndex = 3;
1666 }
1667 if (styleIndex == -1 && !lcName.equalsIgnoreCase(fd.familyName)) {
1668 return null;
1669 }
1670
1671 String plainFile = null, boldFile = null,
1672 italicFile = null, boldItalicFile = null;
1673
1674 boolean failure = false;
1675
1676
1677
1678
1679
1680
1681 getPlatformFontDirs(noType1Font);
1682
1683 if (fd.plainFileName != null) {
1684 plainFile = getPathName(fd.plainFileName);
1685 if (plainFile == null) {
1686 failure = true;
1687 }
1688 }
1689
1690 if (fd.boldFileName != null) {
1691 boldFile = getPathName(fd.boldFileName);
1692 if (boldFile == null) {
1693 failure = true;
1694 }
1695 }
1696
1697 if (fd.italicFileName != null) {
1698 italicFile = getPathName(fd.italicFileName);
1699 if (italicFile == null) {
1700 failure = true;
1701 }
1702 }
1703
1704 if (fd.boldItalicFileName != null) {
1705 boldItalicFile = getPathName(fd.boldItalicFileName);
1706 if (boldItalicFile == null) {
1707 failure = true;
1708 }
1709 }
1710
1711 if (failure) {
1712 if (FontUtilities.isLogging()) {
1713 FontUtilities.getLogger().
1714 info("Hardcoded file missing looking for " + lcName);
1715 }
1716 platformFontMap.remove(firstWord);
1717 return null;
1718 }
1719
1720
1721 final String[] files = {
1722 plainFile, boldFile, italicFile, boldItalicFile } ;
1723
1724 failure = java.security.AccessController.doPrivileged(
1725 new java.security.PrivilegedAction<Boolean>() {
1726 public Boolean run() {
1727 for (int i=0; i<files.length; i++) {
1728 if (files[i] == null) {
1729 continue;
1730 }
1731 File f = new File(files[i]);
1732 if (!f.exists()) {
1733 return Boolean.TRUE;
1734 }
1735 }
1736 return Boolean.FALSE;
1737 }
1738 });
1739
1740 if (failure) {
1741 if (FontUtilities.isLogging()) {
1742 FontUtilities.getLogger().
1743 info("Hardcoded file missing looking for " + lcName);
1744 }
1745 platformFontMap.remove(firstWord);
1746 return null;
1747 }
1748
1749
1750
1751
1752
1753
1754
1755 Font2D font = null;
1756 for (int f=0;f<files.length;f++) {
1757 if (files[f] == null) {
1758 continue;
1759 }
1760 PhysicalFont pf =
1761 registerFontFile(files[f], null,
1762 FONTFORMAT_TRUETYPE, false, Font2D.TTF_RANK);
1763 if (f == styleIndex) {
1764 font = pf;
1765 }
1766 }
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781 FontFamily fontFamily = FontFamily.getFamily(fd.familyName);
1782 if (fontFamily != null) {
1783 if (font == null) {
1784 font = fontFamily.getFont(style);
1785 if (font == null) {
1786 font = fontFamily.getClosestStyle(style);
1787 }
1788 } else if (style > 0 && style != font.style) {
1789 style |= font.style;
1790 font = fontFamily.getFont(style);
1791 if (font == null) {
1792 font = fontFamily.getClosestStyle(style);
1793 }
1794 }
1795 }
1796
1797 return font;
1798 }
1799 private synchronized HashMap<String,String> getFullNameToFileMap() {
1800 if (fontToFileMap == null) {
1801
1802 pathDirs = getPlatformFontDirs(noType1Font);
1803
1804 fontToFileMap = new HashMap<String,String>(100);
1805 fontToFamilyNameMap = new HashMap<String,String>(100);
1806 familyToFontListMap = new HashMap<String,ArrayList<String>>(50);
1807 populateFontFileNameMap(fontToFileMap,
1808 fontToFamilyNameMap,
1809 familyToFontListMap,
1810 Locale.ENGLISH);
1811 if (FontUtilities.isWindows) {
1812 resolveWindowsFonts();
1813 }
1814 if (FontUtilities.isLogging()) {
1815 logPlatformFontInfo();
1816 }
1817 }
1818 return fontToFileMap;
1819 }
1820
1821 private void logPlatformFontInfo() {
1822 PlatformLogger logger = FontUtilities.getLogger();
1823 for (int i=0; i< pathDirs.length;i++) {
1824 logger.info("fontdir="+pathDirs[i]);
1825 }
1826 for (String keyName : fontToFileMap.keySet()) {
1827 logger.info("font="+keyName+" file="+ fontToFileMap.get(keyName));
1828 }
1829 for (String keyName : fontToFamilyNameMap.keySet()) {
1830 logger.info("font="+keyName+" family="+
1831 fontToFamilyNameMap.get(keyName));
1832 }
1833 for (String keyName : familyToFontListMap.keySet()) {
1834 logger.info("family="+keyName+ " fonts="+
1835 familyToFontListMap.get(keyName));
1836 }
1837 }
1838
1839
1840 protected String[] getFontNamesFromPlatform() {
1841 if (getFullNameToFileMap().size() == 0) {
1842 return null;
1843 }
1844 checkForUnreferencedFontFiles();
1845
1846
1847 ArrayList<String> fontNames = new ArrayList<String>();
1848 for (ArrayList<String> a : familyToFontListMap.values()) {
1849 for (String s : a) {
1850 fontNames.add(s);
1851 }
1852 }
1853 return fontNames.toArray(STR_ARRAY);
1854 }
1855
1856 public boolean gotFontsFromPlatform() {
1857 return getFullNameToFileMap().size() != 0;
1858 }
1859
1860 public String getFileNameForFontName(String fontName) {
1861 String fontNameLC = fontName.toLowerCase(Locale.ENGLISH);
1862 return fontToFileMap.get(fontNameLC);
1863 }
1864
1865 private PhysicalFont registerFontFile(String file) {
1866 if (new File(file).isAbsolute() &&
1867 !registeredFonts.contains(file)) {
1868 int fontFormat = FONTFORMAT_NONE;
1869 int fontRank = Font2D.UNKNOWN_RANK;
1870 if (ttFilter.accept(null, file)) {
1871 fontFormat = FONTFORMAT_TRUETYPE;
1872 fontRank = Font2D.TTF_RANK;
1873 } else if
1874 (t1Filter.accept(null, file)) {
1875 fontFormat = FONTFORMAT_TYPE1;
1876 fontRank = Font2D.TYPE1_RANK;
1877 }
1878 if (fontFormat == FONTFORMAT_NONE) {
1879 return null;
1880 }
1881 return registerFontFile(file, null, fontFormat, false, fontRank);
1882 }
1883 return null;
1884 }
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894 protected void registerOtherFontFiles(HashSet registeredFontFiles) {
1895 if (getFullNameToFileMap().size() == 0) {
1896 return;
1897 }
1898 for (String file : fontToFileMap.values()) {
1899 registerFontFile(file);
1900 }
1901 }
1902
1903 public boolean
1904 getFamilyNamesFromPlatform(TreeMap<String,String> familyNames,
1905 Locale requestedLocale) {
1906 if (getFullNameToFileMap().size() == 0) {
1907 return false;
1908 }
1909 checkForUnreferencedFontFiles();
1910 for (String name : fontToFamilyNameMap.values()) {
1911 familyNames.put(name.toLowerCase(requestedLocale), name);
1912 }
1913 return true;
1914 }
1915
1916
1917
1918
1919 private String getPathName(final String s) {
1920 File f = new File(s);
1921 if (f.isAbsolute()) {
1922 return s;
1923 } else if (pathDirs.length==1) {
1924 return pathDirs[0] + File.separator + s;
1925 } else {
1926 String path = java.security.AccessController.doPrivileged(
1927 new java.security.PrivilegedAction<String>() {
1928 public String run() {
1929 for (int p=0; p<pathDirs.length; p++) {
1930 File f = new File(pathDirs[p] +File.separator+ s);
1931 if (f.exists()) {
1932 return f.getAbsolutePath();
1933 }
1934 }
1935 return null;
1936 }
1937 });
1938 if (path != null) {
1939 return path;
1940 }
1941 }
1942 return s;
1943 }
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965 private Font2D findFontFromPlatform(String lcName, int style) {
1966 if (getFullNameToFileMap().size() == 0) {
1967 return null;
1968 }
1969
1970 ArrayList<String> family = null;
1971 String fontFile = null;
1972 String familyName = fontToFamilyNameMap.get(lcName);
1973 if (familyName != null) {
1974 fontFile = fontToFileMap.get(lcName);
1975 family = familyToFontListMap.get
1976 (familyName.toLowerCase(Locale.ENGLISH));
1977 } else {
1978 family = familyToFontListMap.get(lcName);
1979 if (family != null && family.size() > 0) {
1980 String lcFontName = family.get(0).toLowerCase(Locale.ENGLISH);
1981 if (lcFontName != null) {
1982 familyName = fontToFamilyNameMap.get(lcFontName);
1983 }
1984 }
1985 }
1986 if (family == null || familyName == null) {
1987 return null;
1988 }
1989 String [] fontList = (String[])family.toArray(STR_ARRAY);
1990 if (fontList.length == 0) {
1991 return null;
1992 }
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005 for (int f=0;f<fontList.length;f++) {
2006 String fontNameLC = fontList[f].toLowerCase(Locale.ENGLISH);
2007 String fileName = fontToFileMap.get(fontNameLC);
2008 if (fileName == null) {
2009 if (FontUtilities.isLogging()) {
2010 FontUtilities.getLogger()
2011 .info("Platform lookup : No file for font " +
2012 fontList[f] + " in family " +familyName);
2013 }
2014 return null;
2015 }
2016 }
2017
2018
2019
2020
2021 PhysicalFont physicalFont = null;
2022 if (fontFile != null) {
2023 physicalFont = registerFontFile(getPathName(fontFile), null,
2024 FONTFORMAT_TRUETYPE, false,
2025 Font2D.TTF_RANK);
2026 }
2027
2028 for (int f=0;f<fontList.length;f++) {
2029 String fontNameLC = fontList[f].toLowerCase(Locale.ENGLISH);
2030 String fileName = fontToFileMap.get(fontNameLC);
2031 if (fontFile != null && fontFile.equals(fileName)) {
2032 continue;
2033 }
2034
2035
2036
2037 registerFontFile(getPathName(fileName), null,
2038 FONTFORMAT_TRUETYPE, false, Font2D.TTF_RANK);
2039 }
2040
2041 Font2D font = null;
2042 FontFamily fontFamily = FontFamily.getFamily(familyName);
2043
2044 if (physicalFont != null) {
2045 style |= physicalFont.style;
2046 }
2047 if (fontFamily != null) {
2048 font = fontFamily.getFont(style);
2049 if (font == null) {
2050 font = fontFamily.getClosestStyle(style);
2051 }
2052 }
2053 return font;
2054 }
2055
2056 private ConcurrentHashMap<String, Font2D> fontNameCache =
2057 new ConcurrentHashMap<String, Font2D>();
2058
2059
2060
2061
2062
2063
2064
2065
2066 public Font2D findFont2D(String name, int style, int fallback) {
2067 String lowerCaseName = name.toLowerCase(Locale.ENGLISH);
2068 String mapName = lowerCaseName + dotStyleStr(style);
2069 Font2D font;
2070
2071
2072
2073
2074
2075
2076
2077 if (_usingPerAppContextComposites) {
2078 ConcurrentHashMap<String, Font2D> altNameCache =
2079 (ConcurrentHashMap<String, Font2D>)
2080 AppContext.getAppContext().get(CompositeFont.class);
2081 if (altNameCache != null) {
2082 font = (Font2D)altNameCache.get(mapName);
2083 } else {
2084 font = null;
2085 }
2086 } else {
2087 font = fontNameCache.get(mapName);
2088 }
2089 if (font != null) {
2090 return font;
2091 }
2092
2093 if (FontUtilities.isLogging()) {
2094 FontUtilities.getLogger().info("Search for font: " + name);
2095 }
2096
2097
2098
2099
2100
2101
2102
2103 if (FontUtilities.isWindows) {
2104 if (lowerCaseName.equals("ms sans serif")) {
2105 name = "sansserif";
2106 } else if (lowerCaseName.equals("ms serif")) {
2107 name = "serif";
2108 }
2109 }
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119 if (lowerCaseName.equals("default")) {
2120 name = "dialog";
2121 }
2122
2123
2124 FontFamily family = FontFamily.getFamily(name);
2125 if (family != null) {
2126 font = family.getFontWithExactStyleMatch(style);
2127 if (font == null) {
2128 font = findDeferredFont(name, style);
2129 }
2130 if (font == null) {
2131 font = family.getFont(style);
2132 }
2133 if (font == null) {
2134 font = family.getClosestStyle(style);
2135 }
2136 if (font != null) {
2137 fontNameCache.put(mapName, font);
2138 return font;
2139 }
2140 }
2141
2142
2143
2144
2145 font = fullNameToFont.get(lowerCaseName);
2146 if (font != null) {
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159 if (font.style == style || style == Font.PLAIN) {
2160 fontNameCache.put(mapName, font);
2161 return font;
2162 } else {
2163
2164
2165
2166
2167
2168
2169 family = FontFamily.getFamily(font.getFamilyName(null));
2170 if (family != null) {
2171 Font2D familyFont = family.getFont(style|font.style);
2172
2173 if (familyFont != null) {
2174 fontNameCache.put(mapName, familyFont);
2175 return familyFont;
2176 } else {
2177
2178
2179
2180
2181
2182 familyFont = family.getClosestStyle(style|font.style);
2183 if (familyFont != null) {
2184
2185
2186
2187
2188
2189
2190
2191 if (familyFont.canDoStyle(style|font.style)) {
2192 fontNameCache.put(mapName, familyFont);
2193 return familyFont;
2194 }
2195 }
2196 }
2197 }
2198 }
2199 }
2200
2201 if (FontUtilities.isWindows) {
2202
2203 font = findFontFromPlatformMap(lowerCaseName, style);
2204 if (FontUtilities.isLogging()) {
2205 FontUtilities.getLogger()
2206 .info("findFontFromPlatformMap returned " + font);
2207 }
2208 if (font != null) {
2209 fontNameCache.put(mapName, font);
2210 return font;
2211 }
2212
2213
2214
2215
2216 if (deferredFontFiles.size() > 0) {
2217 font = findJREDeferredFont(lowerCaseName, style);
2218 if (font != null) {
2219 fontNameCache.put(mapName, font);
2220 return font;
2221 }
2222 }
2223 font = findFontFromPlatform(lowerCaseName, style);
2224 if (font != null) {
2225 if (FontUtilities.isLogging()) {
2226 FontUtilities.getLogger()
2227 .info("Found font via platform API for request:\"" +
2228 name + "\":, style="+style+
2229 " found font: " + font);
2230 }
2231 fontNameCache.put(mapName, font);
2232 return font;
2233 }
2234 }
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248 if (deferredFontFiles.size() > 0) {
2249 font = findDeferredFont(name, style);
2250 if (font != null) {
2251 fontNameCache.put(mapName, font);
2252 return font;
2253 }
2254 }
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269 if (FontUtilities.isSolaris &&!loaded1dot0Fonts) {
2270
2271
2272
2273 if (lowerCaseName.equals("timesroman")) {
2274 font = findFont2D("serif", style, fallback);
2275 fontNameCache.put(mapName, font);
2276 }
2277 register1dot0Fonts();
2278 loaded1dot0Fonts = true;
2279 Font2D ff = findFont2D(name, style, fallback);
2280 return ff;
2281 }
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293 if (fontsAreRegistered || fontsAreRegisteredPerAppContext) {
2294 Hashtable<String, FontFamily> familyTable = null;
2295 Hashtable<String, Font2D> nameTable;
2296
2297 if (fontsAreRegistered) {
2298 familyTable = createdByFamilyName;
2299 nameTable = createdByFullName;
2300 } else {
2301 AppContext appContext = AppContext.getAppContext();
2302 familyTable =
2303 (Hashtable<String,FontFamily>)appContext.get(regFamilyKey);
2304 nameTable =
2305 (Hashtable<String,Font2D>)appContext.get(regFullNameKey);
2306 }
2307
2308 family = familyTable.get(lowerCaseName);
2309 if (family != null) {
2310 font = family.getFontWithExactStyleMatch(style);
2311 if (font == null) {
2312 font = family.getFont(style);
2313 }
2314 if (font == null) {
2315 font = family.getClosestStyle(style);
2316 }
2317 if (font != null) {
2318 if (fontsAreRegistered) {
2319 fontNameCache.put(mapName, font);
2320 }
2321 return font;
2322 }
2323 }
2324 font = nameTable.get(lowerCaseName);
2325 if (font != null) {
2326 if (fontsAreRegistered) {
2327 fontNameCache.put(mapName, font);
2328 }
2329 return font;
2330 }
2331 }
2332
2333
2334
2335
2336 if (!loadedAllFonts) {
2337 if (FontUtilities.isLogging()) {
2338 FontUtilities.getLogger()
2339 .info("Load fonts looking for:" + name);
2340 }
2341 loadFonts();
2342 loadedAllFonts = true;
2343 return findFont2D(name, style, fallback);
2344 }
2345
2346 if (!loadedAllFontFiles) {
2347 if (FontUtilities.isLogging()) {
2348 FontUtilities.getLogger()
2349 .info("Load font files looking for:" + name);
2350 }
2351 loadFontFiles();
2352 loadedAllFontFiles = true;
2353 return findFont2D(name, style, fallback);
2354 }
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371 if ((font = findFont2DAllLocales(name, style)) != null) {
2372 fontNameCache.put(mapName, font);
2373 return font;
2374 }
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386 if (FontUtilities.isWindows) {
2387 String compatName =
2388 getFontConfiguration().getFallbackFamilyName(name, null);
2389 if (compatName != null) {
2390 font = findFont2D(compatName, style, fallback);
2391 fontNameCache.put(mapName, font);
2392 return font;
2393 }
2394 } else if (lowerCaseName.equals("timesroman")) {
2395 font = findFont2D("serif", style, fallback);
2396 fontNameCache.put(mapName, font);
2397 return font;
2398 } else if (lowerCaseName.equals("helvetica")) {
2399 font = findFont2D("sansserif", style, fallback);
2400 fontNameCache.put(mapName, font);
2401 return font;
2402 } else if (lowerCaseName.equals("courier")) {
2403 font = findFont2D("monospaced", style, fallback);
2404 fontNameCache.put(mapName, font);
2405 return font;
2406 }
2407
2408 if (FontUtilities.isLogging()) {
2409 FontUtilities.getLogger().info("No font found for:" + name);
2410 }
2411
2412 switch (fallback) {
2413 case PHYSICAL_FALLBACK: return getDefaultPhysicalFont();
2414 case LOGICAL_FALLBACK: return getDefaultLogicalFont(style);
2415 default: return null;
2416 }
2417 }
2418
2419
2420
2421
2422
2423
2424 public boolean usePlatformFontMetrics() {
2425 return usePlatformFontMetrics;
2426 }
2427
2428 public int getNumFonts() {
2429 return physicalFonts.size()+maxCompFont;
2430 }
2431
2432 private static boolean fontSupportsEncoding(Font font, String encoding) {
2433 return FontUtilities.getFont2D(font).supportsEncoding(encoding);
2434 }
2435
2436 protected abstract String getFontPath(boolean noType1Fonts);
2437
2438 private Thread fileCloser = null;
2439 Vector<File> tmpFontFiles = null;
2440
2441 public Font2D createFont2D(File fontFile, int fontFormat,
2442 boolean isCopy, CreatedFontTracker tracker)
2443 throws FontFormatException {
2444
2445 String fontFilePath = fontFile.getPath();
2446 FileFont font2D = null;
2447 final File fFile = fontFile;
2448 final CreatedFontTracker _tracker = tracker;
2449 try {
2450 switch (fontFormat) {
2451 case Font.TRUETYPE_FONT:
2452 font2D = new TrueTypeFont(fontFilePath, null, 0, true);
2453 break;
2454 case Font.TYPE1_FONT:
2455 font2D = new Type1Font(fontFilePath, null, isCopy);
2456 break;
2457 default:
2458 throw new FontFormatException("Unrecognised Font Format");
2459 }
2460 } catch (FontFormatException e) {
2461 if (isCopy) {
2462 java.security.AccessController.doPrivileged(
2463 new java.security.PrivilegedAction() {
2464 public Object run() {
2465 if (_tracker != null) {
2466 _tracker.subBytes((int)fFile.length());
2467 }
2468 fFile.delete();
2469 return null;
2470 }
2471 });
2472 }
2473 throw(e);
2474 }
2475 if (isCopy) {
2476 font2D.setFileToRemove(fontFile, tracker);
2477 synchronized (FontManager.class) {
2478
2479 if (tmpFontFiles == null) {
2480 tmpFontFiles = new Vector<File>();
2481 }
2482 tmpFontFiles.add(fontFile);
2483
2484 if (fileCloser == null) {
2485 final Runnable fileCloserRunnable = new Runnable() {
2486 public void run() {
2487 java.security.AccessController.doPrivileged(
2488 new java.security.PrivilegedAction() {
2489 public Object run() {
2490
2491 for (int i=0;i<CHANNELPOOLSIZE;i++) {
2492 if (fontFileCache[i] != null) {
2493 try {
2494 fontFileCache[i].close();
2495 } catch (Exception e) {
2496 }
2497 }
2498 }
2499 if (tmpFontFiles != null) {
2500 File[] files = new File[tmpFontFiles.size()];
2501 files = tmpFontFiles.toArray(files);
2502 for (int f=0; f<files.length;f++) {
2503 try {
2504 files[f].delete();
2505 } catch (Exception e) {
2506 }
2507 }
2508 }
2509
2510 return null;
2511 }
2512
2513 });
2514 }
2515 };
2516 java.security.AccessController.doPrivileged(
2517 new java.security.PrivilegedAction() {
2518 public Object run() {
2519
2520
2521
2522
2523 ThreadGroup tg =
2524 Thread.currentThread().getThreadGroup();
2525 for (ThreadGroup tgn = tg;
2526 tgn != null;
2527 tg = tgn, tgn = tg.getParent());
2528 fileCloser = new Thread(tg, fileCloserRunnable);
2529 fileCloser.setContextClassLoader(null);
2530 Runtime.getRuntime().addShutdownHook(fileCloser);
2531 return null;
2532 }
2533 });
2534 }
2535 }
2536 }
2537 return font2D;
2538 }
2539
2540
2541
2542
2543 public synchronized String getFullNameByFileName(String fileName) {
2544 PhysicalFont[] physFonts = getPhysicalFonts();
2545 for (int i=0;i<physFonts.length;i++) {
2546 if (physFonts[i].platName.equals(fileName)) {
2547 return (physFonts[i].getFontName(null));
2548 }
2549 }
2550 return null;
2551 }
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565 public synchronized void deRegisterBadFont(Font2D font2D) {
2566 if (!(font2D instanceof PhysicalFont)) {
2567
2568 return;
2569 } else {
2570 if (FontUtilities.isLogging()) {
2571 FontUtilities.getLogger()
2572 .severe("Deregister bad font: " + font2D);
2573 }
2574 replaceFont((PhysicalFont)font2D, getDefaultPhysicalFont());
2575 }
2576 }
2577
2578
2579
2580
2581
2582 public synchronized void replaceFont(PhysicalFont oldFont,
2583 PhysicalFont newFont) {
2584
2585 if (oldFont.handle.font2D != oldFont) {
2586
2587 return;
2588 }
2589
2590
2591
2592
2593 if (oldFont == newFont) {
2594 if (FontUtilities.isLogging()) {
2595 FontUtilities.getLogger()
2596 .severe("Can't replace bad font with itself " + oldFont);
2597 }
2598 PhysicalFont[] physFonts = getPhysicalFonts();
2599 for (int i=0; i<physFonts.length;i++) {
2600 if (physFonts[i] != newFont) {
2601 newFont = physFonts[i];
2602 break;
2603 }
2604 }
2605 if (oldFont == newFont) {
2606 if (FontUtilities.isLogging()) {
2607 FontUtilities.getLogger()
2608 .severe("This is bad. No good physicalFonts found.");
2609 }
2610 return;
2611 }
2612 }
2613
2614
2615
2616
2617
2618 oldFont.handle.font2D = newFont;
2619 physicalFonts.remove(oldFont.fullName);
2620 fullNameToFont.remove(oldFont.fullName.toLowerCase(Locale.ENGLISH));
2621 FontFamily.remove(oldFont);
2622
2623 if (localeFullNamesToFont != null) {
2624 Map.Entry[] mapEntries =
2625 (Map.Entry[])localeFullNamesToFont.entrySet().
2626 toArray(new Map.Entry[0]);
2627
2628
2629
2630 for (int i=0; i<mapEntries.length;i++) {
2631 if (mapEntries[i].getValue() == oldFont) {
2632 try {
2633 mapEntries[i].setValue(newFont);
2634 } catch (Exception e) {
2635
2636
2637
2638 localeFullNamesToFont.remove(mapEntries[i].getKey());
2639 }
2640 }
2641 }
2642 }
2643
2644 for (int i=0; i<maxCompFont; i++) {
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674 if (newFont.getRank() > Font2D.FONT_CONFIG_RANK) {
2675 compFonts[i].replaceComponentFont(oldFont, newFont);
2676 }
2677 }
2678 }
2679
2680 private synchronized void loadLocaleNames() {
2681 if (localeFullNamesToFont != null) {
2682 return;
2683 }
2684 localeFullNamesToFont = new HashMap<String, TrueTypeFont>();
2685 Font2D[] fonts = getRegisteredFonts();
2686 for (int i=0; i<fonts.length; i++) {
2687 if (fonts[i] instanceof TrueTypeFont) {
2688 TrueTypeFont ttf = (TrueTypeFont)fonts[i];
2689 String[] fullNames = ttf.getAllFullNames();
2690 for (int n=0; n<fullNames.length; n++) {
2691 localeFullNamesToFont.put(fullNames[n], ttf);
2692 }
2693 FontFamily family = FontFamily.getFamily(ttf.familyName);
2694 if (family != null) {
2695 FontFamily.addLocaleNames(family, ttf.getAllFamilyNames());
2696 }
2697 }
2698 }
2699 }
2700
2701
2702
2703
2704
2705
2706
2707
2708 private Font2D findFont2DAllLocales(String name, int style) {
2709
2710 if (FontUtilities.isLogging()) {
2711 FontUtilities.getLogger()
2712 .info("Searching localised font names for:" + name);
2713 }
2714
2715
2716
2717
2718
2719 if (localeFullNamesToFont == null) {
2720 loadLocaleNames();
2721 }
2722 String lowerCaseName = name.toLowerCase();
2723 Font2D font = null;
2724
2725
2726 FontFamily family = FontFamily.getLocaleFamily(lowerCaseName);
2727 if (family != null) {
2728 font = family.getFont(style);
2729 if (font == null) {
2730 font = family.getClosestStyle(style);
2731 }
2732 if (font != null) {
2733 return font;
2734 }
2735 }
2736
2737
2738 synchronized (this) {
2739 font = localeFullNamesToFont.get(name);
2740 }
2741 if (font != null) {
2742 if (font.style == style || style == Font.PLAIN) {
2743 return font;
2744 } else {
2745 family = FontFamily.getFamily(font.getFamilyName(null));
2746 if (family != null) {
2747 Font2D familyFont = family.getFont(style);
2748
2749 if (familyFont != null) {
2750 return familyFont;
2751 } else {
2752 familyFont = family.getClosestStyle(style);
2753 if (familyFont != null) {
2754
2755
2756
2757
2758
2759
2760
2761
2762 if (!familyFont.canDoStyle(style)) {
2763 familyFont = null;
2764 }
2765 return familyFont;
2766 }
2767 }
2768 }
2769 }
2770 }
2771 return font;
2772 }
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823 private static final Object altJAFontKey = new Object();
2824 private static final Object localeFontKey = new Object();
2825 private static final Object proportionalFontKey = new Object();
2826 private boolean _usingPerAppContextComposites = false;
2827 private boolean _usingAlternateComposites = false;
2828
2829
2830
2831
2832 private static boolean gAltJAFont = false;
2833 private boolean gLocalePref = false;
2834 private boolean gPropPref = false;
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849 public boolean maybeUsingAlternateCompositeFonts() {
2850 return _usingAlternateComposites || _usingPerAppContextComposites;
2851 }
2852
2853 public boolean usingAlternateCompositeFonts() {
2854 return (_usingAlternateComposites ||
2855 (_usingPerAppContextComposites &&
2856 AppContext.getAppContext().get(CompositeFont.class) != null));
2857 }
2858
2859 private static boolean maybeMultiAppContext() {
2860 Boolean appletSM = (Boolean)
2861 java.security.AccessController.doPrivileged(
2862 new java.security.PrivilegedAction() {
2863 public Object run() {
2864 SecurityManager sm = System.getSecurityManager();
2865 return new Boolean
2866 (sm instanceof sun.applet.AppletSecurity);
2867 }
2868 });
2869 return appletSM.booleanValue();
2870 }
2871
2872
2873
2874
2875
2876 public synchronized void useAlternateFontforJALocales() {
2877 if (FontUtilities.isLogging()) {
2878 FontUtilities.getLogger()
2879 .info("Entered useAlternateFontforJALocales().");
2880 }
2881 if (!FontUtilities.isWindows) {
2882 return;
2883 }
2884
2885 if (!maybeMultiAppContext()) {
2886 gAltJAFont = true;
2887 } else {
2888 AppContext appContext = AppContext.getAppContext();
2889 appContext.put(altJAFontKey, altJAFontKey);
2890 }
2891 }
2892
2893 public boolean usingAlternateFontforJALocales() {
2894 if (!maybeMultiAppContext()) {
2895 return gAltJAFont;
2896 } else {
2897 AppContext appContext = AppContext.getAppContext();
2898 return appContext.get(altJAFontKey) == altJAFontKey;
2899 }
2900 }
2901
2902 public synchronized void preferLocaleFonts() {
2903 if (FontUtilities.isLogging()) {
2904 FontUtilities.getLogger().info("Entered preferLocaleFonts().");
2905 }
2906
2907 if (!FontConfiguration.willReorderForStartupLocale()) {
2908 return;
2909 }
2910
2911 if (!maybeMultiAppContext()) {
2912 if (gLocalePref == true) {
2913 return;
2914 }
2915 gLocalePref = true;
2916 createCompositeFonts(fontNameCache, gLocalePref, gPropPref);
2917 _usingAlternateComposites = true;
2918 } else {
2919 AppContext appContext = AppContext.getAppContext();
2920 if (appContext.get(localeFontKey) == localeFontKey) {
2921 return;
2922 }
2923 appContext.put(localeFontKey, localeFontKey);
2924 boolean acPropPref =
2925 appContext.get(proportionalFontKey) == proportionalFontKey;
2926 ConcurrentHashMap<String, Font2D>
2927 altNameCache = new ConcurrentHashMap<String, Font2D> ();
2928
2929 appContext.put(CompositeFont.class, altNameCache);
2930 _usingPerAppContextComposites = true;
2931 createCompositeFonts(altNameCache, true, acPropPref);
2932 }
2933 }
2934
2935 public synchronized void preferProportionalFonts() {
2936 if (FontUtilities.isLogging()) {
2937 FontUtilities.getLogger()
2938 .info("Entered preferProportionalFonts().");
2939 }
2940
2941
2942
2943 if (!FontConfiguration.hasMonoToPropMap()) {
2944 return;
2945 }
2946
2947 if (!maybeMultiAppContext()) {
2948 if (gPropPref == true) {
2949 return;
2950 }
2951 gPropPref = true;
2952 createCompositeFonts(fontNameCache, gLocalePref, gPropPref);
2953 _usingAlternateComposites = true;
2954 } else {
2955 AppContext appContext = AppContext.getAppContext();
2956 if (appContext.get(proportionalFontKey) == proportionalFontKey) {
2957 return;
2958 }
2959 appContext.put(proportionalFontKey, proportionalFontKey);
2960 boolean acLocalePref =
2961 appContext.get(localeFontKey) == localeFontKey;
2962 ConcurrentHashMap<String, Font2D>
2963 altNameCache = new ConcurrentHashMap<String, Font2D> ();
2964
2965 appContext.put(CompositeFont.class, altNameCache);
2966 _usingPerAppContextComposites = true;
2967 createCompositeFonts(altNameCache, acLocalePref, true);
2968 }
2969 }
2970
2971 private static HashSet<String> installedNames = null;
2972 private static HashSet<String> getInstalledNames() {
2973 if (installedNames == null) {
2974 Locale l = getSystemStartupLocale();
2975 SunFontManager fontManager = SunFontManager.getInstance();
2976 String[] installedFamilies =
2977 fontManager.getInstalledFontFamilyNames(l);
2978 Font[] installedFonts = fontManager.getAllInstalledFonts();
2979 HashSet<String> names = new HashSet<String>();
2980 for (int i=0; i<installedFamilies.length; i++) {
2981 names.add(installedFamilies[i].toLowerCase(l));
2982 }
2983 for (int i=0; i<installedFonts.length; i++) {
2984 names.add(installedFonts[i].getFontName(l).toLowerCase(l));
2985 }
2986 installedNames = names;
2987 }
2988 return installedNames;
2989 }
2990
2991
2992 private static final Object regFamilyKey = new Object();
2993 private static final Object regFullNameKey = new Object();
2994 private Hashtable<String,FontFamily> createdByFamilyName;
2995 private Hashtable<String,Font2D> createdByFullName;
2996 private boolean fontsAreRegistered = false;
2997 private boolean fontsAreRegisteredPerAppContext = false;
2998
2999 public boolean registerFont(Font font) {
3000
3001
3002
3003 if (font == null) {
3004 return false;
3005 }
3006
3007
3008 synchronized (regFamilyKey) {
3009 if (createdByFamilyName == null) {
3010 createdByFamilyName = new Hashtable<String,FontFamily>();
3011 createdByFullName = new Hashtable<String,Font2D>();
3012 }
3013 }
3014
3015 if (! FontAccess.getFontAccess().isCreatedFont(font)) {
3016 return false;
3017 }
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036 HashSet<String> names = getInstalledNames();
3037 Locale l = getSystemStartupLocale();
3038 String familyName = font.getFamily(l).toLowerCase();
3039 String fullName = font.getFontName(l).toLowerCase();
3040 if (names.contains(familyName) || names.contains(fullName)) {
3041 return false;
3042 }
3043
3044
3045 Hashtable<String,FontFamily> familyTable;
3046 Hashtable<String,Font2D> fullNameTable;
3047 if (!maybeMultiAppContext()) {
3048 familyTable = createdByFamilyName;
3049 fullNameTable = createdByFullName;
3050 fontsAreRegistered = true;
3051 } else {
3052 AppContext appContext = AppContext.getAppContext();
3053 familyTable =
3054 (Hashtable<String,FontFamily>)appContext.get(regFamilyKey);
3055 fullNameTable =
3056 (Hashtable<String,Font2D>)appContext.get(regFullNameKey);
3057 if (familyTable == null) {
3058 familyTable = new Hashtable<String,FontFamily>();
3059 fullNameTable = new Hashtable<String,Font2D>();
3060 appContext.put(regFamilyKey, familyTable);
3061 appContext.put(regFullNameKey, fullNameTable);
3062 }
3063 fontsAreRegisteredPerAppContext = true;
3064 }
3065
3066 Font2D font2D = FontUtilities.getFont2D(font);
3067 int style = font2D.getStyle();
3068 FontFamily family = familyTable.get(familyName);
3069 if (family == null) {
3070 family = new FontFamily(font.getFamily(l));
3071 familyTable.put(familyName, family);
3072 }
3073
3074
3075
3076
3077
3078
3079 if (fontsAreRegistered) {
3080 removeFromCache(family.getFont(Font.PLAIN));
3081 removeFromCache(family.getFont(Font.BOLD));
3082 removeFromCache(family.getFont(Font.ITALIC));
3083 removeFromCache(family.getFont(Font.BOLD|Font.ITALIC));
3084 removeFromCache(fullNameTable.get(fullName));
3085 }
3086 family.setFont(font2D, style);
3087 fullNameTable.put(fullName, font2D);
3088 return true;
3089 }
3090
3091
3092 private void removeFromCache(Font2D font) {
3093 if (font == null) {
3094 return;
3095 }
3096 String[] keys = (String[])(fontNameCache.keySet().toArray(STR_ARRAY));
3097 for (int k=0; k<keys.length;k++) {
3098 if (fontNameCache.get(keys[k]) == font) {
3099 fontNameCache.remove(keys[k]);
3100 }
3101 }
3102 }
3103
3104
3105 public TreeMap<String, String> getCreatedFontFamilyNames() {
3106
3107 Hashtable<String,FontFamily> familyTable;
3108 if (fontsAreRegistered) {
3109 familyTable = createdByFamilyName;
3110 } else if (fontsAreRegisteredPerAppContext) {
3111 AppContext appContext = AppContext.getAppContext();
3112 familyTable =
3113 (Hashtable<String,FontFamily>)appContext.get(regFamilyKey);
3114 } else {
3115 return null;
3116 }
3117
3118 Locale l = getSystemStartupLocale();
3119 synchronized (familyTable) {
3120 TreeMap<String, String> map = new TreeMap<String, String>();
3121 for (FontFamily f : familyTable.values()) {
3122 Font2D font2D = f.getFont(Font.PLAIN);
3123 if (font2D == null) {
3124 font2D = f.getClosestStyle(Font.PLAIN);
3125 }
3126 String name = font2D.getFamilyName(l);
3127 map.put(name.toLowerCase(l), name);
3128 }
3129 return map;
3130 }
3131 }
3132
3133 public Font[] getCreatedFonts() {
3134
3135 Hashtable<String,Font2D> nameTable;
3136 if (fontsAreRegistered) {
3137 nameTable = createdByFullName;
3138 } else if (fontsAreRegisteredPerAppContext) {
3139 AppContext appContext = AppContext.getAppContext();
3140 nameTable =
3141 (Hashtable<String,Font2D>)appContext.get(regFullNameKey);
3142 } else {
3143 return null;
3144 }
3145
3146 Locale l = getSystemStartupLocale();
3147 synchronized (nameTable) {
3148 Font[] fonts = new Font[nameTable.size()];
3149 int i=0;
3150 for (Font2D font2D : nameTable.values()) {
3151 fonts[i++] = new Font(font2D.getFontName(l), Font.PLAIN, 1);
3152 }
3153 return fonts;
3154 }
3155 }
3156
3157
3158 protected String[] getPlatformFontDirs(boolean noType1Fonts) {
3159
3160
3161 if (pathDirs != null) {
3162 return pathDirs;
3163 }
3164
3165 String path = getPlatformFontPath(noType1Fonts);
3166 StringTokenizer parser =
3167 new StringTokenizer(path, File.pathSeparator);
3168 ArrayList<String> pathList = new ArrayList<String>();
3169 try {
3170 while (parser.hasMoreTokens()) {
3171 pathList.add(parser.nextToken());
3172 }
3173 } catch (NoSuchElementException e) {
3174 }
3175 pathDirs = pathList.toArray(new String[0]);
3176 return pathDirs;
3177 }
3178
3179
3180
3181
3182
3183 public abstract String[] getDefaultPlatformFont();
3184
3185
3186
3187
3188
3189
3190 private void addDirFonts(String dirName, File dirFile,
3191 FilenameFilter filter,
3192 int fontFormat, boolean useJavaRasterizer,
3193 int fontRank,
3194 boolean defer, boolean resolveSymLinks) {
3195 String[] ls = dirFile.list(filter);
3196 if (ls == null || ls.length == 0) {
3197 return;
3198 }
3199 String[] fontNames = new String[ls.length];
3200 String[][] nativeNames = new String[ls.length][];
3201 int fontCount = 0;
3202
3203 for (int i=0; i < ls.length; i++ ) {
3204 File theFile = new File(dirFile, ls[i]);
3205 String fullName = null;
3206 if (resolveSymLinks) {
3207 try {
3208 fullName = theFile.getCanonicalPath();
3209 } catch (IOException e) {
3210 }
3211 }
3212 if (fullName == null) {
3213 fullName = dirName + File.separator + ls[i];
3214 }
3215
3216
3217 if (registeredFontFiles.contains(fullName)) {
3218 continue;
3219 }
3220
3221 if (badFonts != null && badFonts.contains(fullName)) {
3222 if (FontUtilities.debugFonts()) {
3223 FontUtilities.getLogger()
3224 .warning("skip bad font " + fullName);
3225 }
3226 continue;
3227 }
3228
3229 registeredFontFiles.add(fullName);
3230
3231 if (FontUtilities.debugFonts()
3232 && FontUtilities.getLogger().isLoggable(PlatformLogger.INFO)) {
3233 String message = "Registering font " + fullName;
3234 String[] natNames = getNativeNames(fullName, null);
3235 if (natNames == null) {
3236 message += " with no native name";
3237 } else {
3238 message += " with native name(s) " + natNames[0];
3239 for (int nn = 1; nn < natNames.length; nn++) {
3240 message += ", " + natNames[nn];
3241 }
3242 }
3243 FontUtilities.getLogger().info(message);
3244 }
3245 fontNames[fontCount] = fullName;
3246 nativeNames[fontCount++] = getNativeNames(fullName, null);
3247 }
3248 registerFonts(fontNames, nativeNames, fontCount, fontFormat,
3249 useJavaRasterizer, fontRank, defer);
3250 return;
3251 }
3252
3253 protected String[] getNativeNames(String fontFileName,
3254 String platformName) {
3255 return null;
3256 }
3257
3258
3259
3260
3261
3262
3263
3264 protected String getFileNameFromPlatformName(String platformFontName) {
3265 return fontConfig.getFileNameFromPlatformName(platformFontName);
3266 }
3267
3268
3269
3270
3271 public FontConfiguration getFontConfiguration() {
3272 return fontConfig;
3273 }
3274
3275
3276
3277
3278 public String getPlatformFontPath(boolean noType1Font) {
3279 if (fontPath == null) {
3280 fontPath = getFontPath(noType1Font);
3281 }
3282 return fontPath;
3283 }
3284
3285 public static boolean isOpenJDK() {
3286 return FontUtilities.isOpenJDK;
3287 }
3288
3289 protected void loadFonts() {
3290 if (discoveredAllFonts) {
3291 return;
3292 }
3293
3294 synchronized (this) {
3295 if (FontUtilities.debugFonts()) {
3296 Thread.dumpStack();
3297 FontUtilities.getLogger()
3298 .info("SunGraphicsEnvironment.loadFonts() called");
3299 }
3300 initialiseDeferredFonts();
3301
3302 java.security.AccessController.doPrivileged(
3303 new java.security.PrivilegedAction() {
3304 public Object run() {
3305 if (fontPath == null) {
3306 fontPath = getPlatformFontPath(noType1Font);
3307 registerFontDirs(fontPath);
3308 }
3309 if (fontPath != null) {
3310
3311
3312
3313 if (! gotFontsFromPlatform()) {
3314 registerFontsOnPath(fontPath, false,
3315 Font2D.UNKNOWN_RANK,
3316 false, true);
3317 loadedAllFontFiles = true;
3318 }
3319 }
3320 registerOtherFontFiles(registeredFontFiles);
3321 discoveredAllFonts = true;
3322 return null;
3323 }
3324 });
3325 }
3326 }
3327
3328 protected void registerFontDirs(String pathName) {
3329 return;
3330 }
3331
3332 private void registerFontsOnPath(String pathName,
3333 boolean useJavaRasterizer, int fontRank,
3334 boolean defer, boolean resolveSymLinks) {
3335
3336 StringTokenizer parser = new StringTokenizer(pathName,
3337 File.pathSeparator);
3338 try {
3339 while (parser.hasMoreTokens()) {
3340 registerFontsInDir(parser.nextToken(),
3341 useJavaRasterizer, fontRank,
3342 defer, resolveSymLinks);
3343 }
3344 } catch (NoSuchElementException e) {
3345 }
3346 }
3347
3348
3349 public void registerFontsInDir(String dirName) {
3350 registerFontsInDir(dirName, true, Font2D.JRE_RANK, true, false);
3351 }
3352
3353 private void registerFontsInDir(String dirName, boolean useJavaRasterizer,
3354 int fontRank,
3355 boolean defer, boolean resolveSymLinks) {
3356 File pathFile = new File(dirName);
3357 addDirFonts(dirName, pathFile, ttFilter,
3358 FONTFORMAT_TRUETYPE, useJavaRasterizer,
3359 fontRank==Font2D.UNKNOWN_RANK ?
3360 Font2D.TTF_RANK : fontRank,
3361 defer, resolveSymLinks);
3362 addDirFonts(dirName, pathFile, t1Filter,
3363 FONTFORMAT_TYPE1, useJavaRasterizer,
3364 fontRank==Font2D.UNKNOWN_RANK ?
3365 Font2D.TYPE1_RANK : fontRank,
3366 defer, resolveSymLinks);
3367 }
3368
3369 protected void registerFontDir(String path) {
3370 }
3371
3372
3373
3374
3375
3376 public synchronized String getDefaultFontFile() {
3377 if (defaultFontFileName == null) {
3378 initDefaultFonts();
3379 }
3380 return defaultFontFileName;
3381 }
3382
3383 private void initDefaultFonts() {
3384 if (!isOpenJDK()) {
3385 defaultFontName = lucidaFontName;
3386 if (useAbsoluteFontFileNames()) {
3387 defaultFontFileName =
3388 jreFontDirName + File.separator + FontUtilities.LUCIDA_FILE_NAME;
3389 } else {
3390 defaultFontFileName = FontUtilities.LUCIDA_FILE_NAME;
3391 }
3392 }
3393 }
3394
3395
3396
3397
3398
3399 protected boolean useAbsoluteFontFileNames() {
3400 return true;
3401 }
3402
3403
3404
3405
3406 protected abstract FontConfiguration createFontConfiguration();
3407
3408 public abstract FontConfiguration
3409 createFontConfiguration(boolean preferLocaleFonts,
3410 boolean preferPropFonts);
3411
3412
3413
3414
3415
3416
3417 public synchronized String getDefaultFontFaceName() {
3418 if (defaultFontName == null) {
3419 initDefaultFonts();
3420 }
3421 return defaultFontName;
3422 }
3423
3424 public void loadFontFiles() {
3425 loadFonts();
3426 if (loadedAllFontFiles) {
3427 return;
3428 }
3429
3430 synchronized (this) {
3431 if (FontUtilities.debugFonts()) {
3432 Thread.dumpStack();
3433 FontUtilities.getLogger().info("loadAllFontFiles() called");
3434 }
3435 java.security.AccessController.doPrivileged(
3436 new java.security.PrivilegedAction() {
3437 public Object run() {
3438 if (fontPath == null) {
3439 fontPath = getPlatformFontPath(noType1Font);
3440 }
3441 if (fontPath != null) {
3442
3443
3444
3445 registerFontsOnPath(fontPath, false,
3446 Font2D.UNKNOWN_RANK,
3447 false, true);
3448 }
3449 loadedAllFontFiles = true;
3450 return null;
3451 }
3452 });
3453 }
3454 }
3455
3456
3457
3458
3459
3460
3461
3462
3463 private void
3464 initCompositeFonts(FontConfiguration fontConfig,
3465 ConcurrentHashMap<String, Font2D> altNameCache) {
3466
3467 if (FontUtilities.isLogging()) {
3468 FontUtilities.getLogger()
3469 .info("Initialising composite fonts");
3470 }
3471
3472 int numCoreFonts = fontConfig.getNumberCoreFonts();
3473 String[] fcFonts = fontConfig.getPlatformFontNames();
3474 for (int f=0; f<fcFonts.length; f++) {
3475 String platformFontName = fcFonts[f];
3476 String fontFileName =
3477 getFileNameFromPlatformName(platformFontName);
3478 String[] nativeNames = null;
3479 if (fontFileName == null
3480 || fontFileName.equals(platformFontName)) {
3481
3482
3483
3484 fontFileName = platformFontName;
3485 } else {
3486 if (f < numCoreFonts) {
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501 addFontToPlatformFontPath(platformFontName);
3502 }
3503 nativeNames = getNativeNames(fontFileName, platformFontName);
3504 }
3505
3506
3507
3508
3509
3510
3511
3512 registerFontFile(fontFileName, nativeNames,
3513 Font2D.FONT_CONFIG_RANK, true);
3514
3515
3516 }
3517
3518
3519
3520
3521
3522
3523
3524 registerPlatformFontsUsedByFontConfiguration();
3525
3526 CompositeFontDescriptor[] compositeFontInfo
3527 = fontConfig.get2DCompositeFontInfo();
3528 for (int i = 0; i < compositeFontInfo.length; i++) {
3529 CompositeFontDescriptor descriptor = compositeFontInfo[i];
3530 String[] componentFileNames = descriptor.getComponentFileNames();
3531 String[] componentFaceNames = descriptor.getComponentFaceNames();
3532
3533
3534
3535
3536 if (missingFontFiles != null) {
3537 for (int ii=0; ii<componentFileNames.length; ii++) {
3538 if (missingFontFiles.contains(componentFileNames[ii])) {
3539 componentFileNames[ii] = getDefaultFontFile();
3540 componentFaceNames[ii] = getDefaultFontFaceName();
3541 }
3542 }
3543 }
3544
3545
3546
3547
3548
3549
3550
3551 if (altNameCache != null) {
3552 SunFontManager.registerCompositeFont(
3553 descriptor.getFaceName(),
3554 componentFileNames, componentFaceNames,
3555 descriptor.getCoreComponentCount(),
3556 descriptor.getExclusionRanges(),
3557 descriptor.getExclusionRangeLimits(),
3558 true,
3559 altNameCache);
3560 } else {
3561 registerCompositeFont(descriptor.getFaceName(),
3562 componentFileNames, componentFaceNames,
3563 descriptor.getCoreComponentCount(),
3564 descriptor.getExclusionRanges(),
3565 descriptor.getExclusionRangeLimits(),
3566 true);
3567 }
3568 if (FontUtilities.debugFonts()) {
3569 FontUtilities.getLogger()
3570 .info("registered " + descriptor.getFaceName());
3571 }
3572 }
3573 }
3574
3575
3576
3577
3578
3579
3580 protected void addFontToPlatformFontPath(String platformFontName) {
3581 }
3582
3583 protected void registerFontFile(String fontFileName, String[] nativeNames,
3584 int fontRank, boolean defer) {
3585
3586 if (registeredFontFiles.contains(fontFileName)) {
3587 return;
3588 }
3589 int fontFormat;
3590 if (ttFilter.accept(null, fontFileName)) {
3591 fontFormat = FONTFORMAT_TRUETYPE;
3592 } else if (t1Filter.accept(null, fontFileName)) {
3593 fontFormat = FONTFORMAT_TYPE1;
3594 } else {
3595 fontFormat = FONTFORMAT_NATIVE;
3596 }
3597 registeredFontFiles.add(fontFileName);
3598 if (defer) {
3599 registerDeferredFont(fontFileName, fontFileName, nativeNames,
3600 fontFormat, false, fontRank);
3601 } else {
3602 registerFontFile(fontFileName, nativeNames, fontFormat, false,
3603 fontRank);
3604 }
3605 }
3606
3607 protected void registerPlatformFontsUsedByFontConfiguration() {
3608 }
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624 protected void addToMissingFontFileList(String fileName) {
3625 if (missingFontFiles == null) {
3626 missingFontFiles = new HashSet<String>();
3627 }
3628 missingFontFiles.add(fileName);
3629 }
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649 private boolean isNameForRegisteredFile(String fontName) {
3650 String fileName = getFileNameForFontName(fontName);
3651 if (fileName == null) {
3652 return false;
3653 }
3654 return registeredFontFiles.contains(fileName);
3655 }
3656
3657
3658
3659
3660
3661
3662 public void
3663 createCompositeFonts(ConcurrentHashMap<String, Font2D> altNameCache,
3664 boolean preferLocale,
3665 boolean preferProportional) {
3666
3667 FontConfiguration fontConfig =
3668 createFontConfiguration(preferLocale, preferProportional);
3669 initCompositeFonts(fontConfig, altNameCache);
3670 }
3671
3672
3673
3674
3675 public Font[] getAllInstalledFonts() {
3676 if (allFonts == null) {
3677 loadFonts();
3678 TreeMap fontMapNames = new TreeMap();
3679
3680
3681
3682
3683 Font2D[] allfonts = getRegisteredFonts();
3684 for (int i=0; i < allfonts.length; i++) {
3685 if (!(allfonts[i] instanceof NativeFont)) {
3686 fontMapNames.put(allfonts[i].getFontName(null),
3687 allfonts[i]);
3688 }
3689 }
3690
3691 String[] platformNames = getFontNamesFromPlatform();
3692 if (platformNames != null) {
3693 for (int i=0; i<platformNames.length; i++) {
3694 if (!isNameForRegisteredFile(platformNames[i])) {
3695 fontMapNames.put(platformNames[i], null);
3696 }
3697 }
3698 }
3699
3700 String[] fontNames = null;
3701 if (fontMapNames.size() > 0) {
3702 fontNames = new String[fontMapNames.size()];
3703 Object [] keyNames = fontMapNames.keySet().toArray();
3704 for (int i=0; i < keyNames.length; i++) {
3705 fontNames[i] = (String)keyNames[i];
3706 }
3707 }
3708 Font[] fonts = new Font[fontNames.length];
3709 for (int i=0; i < fontNames.length; i++) {
3710 fonts[i] = new Font(fontNames[i], Font.PLAIN, 1);
3711 Font2D f2d = (Font2D)fontMapNames.get(fontNames[i]);
3712 if (f2d != null) {
3713 FontAccess.getFontAccess().setFont2D(fonts[i], f2d.handle);
3714 }
3715 }
3716 allFonts = fonts;
3717 }
3718
3719 Font []copyFonts = new Font[allFonts.length];
3720 System.arraycopy(allFonts, 0, copyFonts, 0, allFonts.length);
3721 return copyFonts;
3722 }
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732 public String[] getInstalledFontFamilyNames(Locale requestedLocale) {
3733 if (requestedLocale == null) {
3734 requestedLocale = Locale.getDefault();
3735 }
3736 if (allFamilies != null && lastDefaultLocale != null &&
3737 requestedLocale.equals(lastDefaultLocale)) {
3738 String[] copyFamilies = new String[allFamilies.length];
3739 System.arraycopy(allFamilies, 0, copyFamilies,
3740 0, allFamilies.length);
3741 return copyFamilies;
3742 }
3743
3744 TreeMap<String,String> familyNames = new TreeMap<String,String>();
3745
3746 String str;
3747 str = Font.SERIF; familyNames.put(str.toLowerCase(), str);
3748 str = Font.SANS_SERIF; familyNames.put(str.toLowerCase(), str);
3749 str = Font.MONOSPACED; familyNames.put(str.toLowerCase(), str);
3750 str = Font.DIALOG; familyNames.put(str.toLowerCase(), str);
3751 str = Font.DIALOG_INPUT; familyNames.put(str.toLowerCase(), str);
3752
3753
3754
3755
3756
3757 if (requestedLocale.equals(getSystemStartupLocale()) &&
3758 getFamilyNamesFromPlatform(familyNames, requestedLocale)) {
3759
3760 getJREFontFamilyNames(familyNames, requestedLocale);
3761 } else {
3762 loadFontFiles();
3763 Font2D[] physicalfonts = getPhysicalFonts();
3764 for (int i=0; i < physicalfonts.length; i++) {
3765 if (!(physicalfonts[i] instanceof NativeFont)) {
3766 String name =
3767 physicalfonts[i].getFamilyName(requestedLocale);
3768 familyNames.put(name.toLowerCase(requestedLocale), name);
3769 }
3770 }
3771 }
3772
3773 String[] retval = new String[familyNames.size()];
3774 Object [] keyNames = familyNames.keySet().toArray();
3775 for (int i=0; i < keyNames.length; i++) {
3776 retval[i] = (String)familyNames.get(keyNames[i]);
3777 }
3778 if (requestedLocale.equals(Locale.getDefault())) {
3779 lastDefaultLocale = requestedLocale;
3780 allFamilies = new String[retval.length];
3781 System.arraycopy(retval, 0, allFamilies, 0, allFamilies.length);
3782 }
3783 return retval;
3784 }
3785
3786 public void register1dot0Fonts() {
3787 java.security.AccessController.doPrivileged(
3788 new java.security.PrivilegedAction() {
3789 public Object run() {
3790 String type1Dir = "/usr/openwin/lib/X11/fonts/Type1";
3791 registerFontsInDir(type1Dir, true, Font2D.TYPE1_RANK,
3792 false, false);
3793 return null;
3794 }
3795 });
3796 }
3797
3798
3799
3800
3801
3802 protected void getJREFontFamilyNames(TreeMap<String,String> familyNames,
3803 Locale requestedLocale) {
3804 registerDeferredJREFonts(jreFontDirName);
3805 Font2D[] physicalfonts = getPhysicalFonts();
3806 for (int i=0; i < physicalfonts.length; i++) {
3807 if (!(physicalfonts[i] instanceof NativeFont)) {
3808 String name =
3809 physicalfonts[i].getFamilyName(requestedLocale);
3810 familyNames.put(name.toLowerCase(requestedLocale), name);
3811 }
3812 }
3813 }
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825 private static Locale systemLocale = null;
3826 private static Locale getSystemStartupLocale() {
3827 if (systemLocale == null) {
3828 systemLocale = (Locale)
3829 java.security.AccessController.doPrivileged(
3830 new java.security.PrivilegedAction() {
3831 public Object run() {
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842 String fileEncoding = System.getProperty("file.encoding", "");
3843 String sysEncoding = System.getProperty("sun.jnu.encoding");
3844 if (sysEncoding != null && !sysEncoding.equals(fileEncoding)) {
3845 return Locale.ROOT;
3846 }
3847
3848 String language = System.getProperty("user.language", "en");
3849 String country = System.getProperty("user.country","");
3850 String variant = System.getProperty("user.variant","");
3851 return new Locale(language, country, variant);
3852 }
3853 });
3854 }
3855 return systemLocale;
3856 }
3857
3858 void addToPool(FileFont font) {
3859
3860 FileFont fontFileToClose = null;
3861 int freeSlot = -1;
3862
3863 synchronized (fontFileCache) {
3864
3865
3866
3867
3868
3869
3870
3871 for (int i=0;i<CHANNELPOOLSIZE;i++) {
3872 if (fontFileCache[i] == font) {
3873 return;
3874 }
3875 if (fontFileCache[i] == null && freeSlot < 0) {
3876 freeSlot = i;
3877 }
3878 }
3879 if (freeSlot >= 0) {
3880 fontFileCache[freeSlot] = font;
3881 return;
3882 } else {
3883
3884 fontFileToClose = fontFileCache[lastPoolIndex];
3885 fontFileCache[lastPoolIndex] = font;
3886
3887
3888
3889 lastPoolIndex = (lastPoolIndex+1) % CHANNELPOOLSIZE;
3890 }
3891 }
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902 if (fontFileToClose != null) {
3903 fontFileToClose.close();
3904 }
3905 }
3906
3907 protected FontUIResource getFontConfigFUIR(String family, int style,
3908 int size)
3909 {
3910 return new FontUIResource(family, style, size);
3911 }
3912 }